package cn.iocoder.yudao.module.member.service.user;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.*;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.ip.core.utils.IPUtils;
import cn.iocoder.yudao.module.member.api.point.MemberPointApi;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
import cn.iocoder.yudao.module.member.controller.app.user.vo.*;
import cn.iocoder.yudao.module.member.convert.auth.AuthConvert;
import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
import cn.iocoder.yudao.module.member.mq.producer.user.MemberUserProducer;
import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService;
import cn.iocoder.yudao.module.mp.api.user.MpUserApi;
import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
import cn.iocoder.yudao.module.system.api.social.SocialClientApi;
import cn.iocoder.yudao.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO;
import cn.iocoder.yudao.module.system.enums.common.SexEnum;
import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
import cn.iocoder.yudao.module.trade.api.config.TradeConfigApi;
import cn.iocoder.yudao.module.trade.api.config.dto.AddressRespDTO;
import cn.iocoder.yudao.module.trade.api.config.dto.TradeConfigRespDTO;
import com.google.common.annotations.VisibleForTesting;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;

/**
 * 会员 User Service 实现类
 *
 * @author 尔加源码
 */
@Service
@Valid
@Slf4j
public class MemberUserServiceImpl implements MemberUserService {

    @Resource
    private MemberUserMapper memberUserMapper;

    @Resource
    private SmsCodeApi smsCodeApi;

    @Resource
    private TradeConfigApi tradeConfigApi;

    @Resource
    private SocialClientApi socialClientApi;

    @Resource
    private MemberPointRecordService memberPointRecordService;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private MemberUserProducer memberUserProducer;

    @Resource
    private MemberPointApi memberPointApi;

    @Resource
    private MpUserApi mpUserApi;

    @Override
    public MemberUserDO getUserByMobile(String mobile) {
        return memberUserMapper.selectByMobile(mobile);
    }

    @Override
    public List<MemberUserDO> getUserListByNickname(String nickname) {
        return memberUserMapper.selectListByNicknameLike(nickname);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MemberUserDO createUserIfAbsent(String mobile, String registerIp, Integer terminal) {
        // 用户已经存在
        MemberUserDO user = memberUserMapper.selectByMobile(mobile);
        if (user != null) {
            return user;
        }
        // 用户不存在，则进行创建
        return createUser(mobile, null, null, registerIp, terminal);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MemberUserDO createUser(String nickname, String avtar, String registerIp, Integer terminal) {
        return createUser(null, nickname, avtar, registerIp, terminal);
    }

    private MemberUserDO createUser(String mobile, String nickname, String avtar,
                                    String registerIp, Integer terminal) {
        // 生成密码
        String password = IdUtil.fastSimpleUUID();
        // 插入用户
        MemberUserDO user = new MemberUserDO();
        user.setMobile(mobile);
        user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
        user.setPassword(encodePassword(password)); // 加密密码
        user.setRegisterIp(registerIp).setRegisterTerminal(terminal);
        user.setNickname(nickname).setAvatar(avtar); // 基础信息

        // 审核标记
        TradeConfigRespDTO configRespDTO = tradeConfigApi.getTradeConfig();
        user.setAuthEnabled(configRespDTO.getAuthEnabled());

        if (StrUtil.isEmpty(nickname)) {
            // 昵称为空时，随机一个名字，避免一些依赖 nickname 的逻辑报错，或者有点丑。例如说，短信发送有昵称时~
            user.setNickname("用户" + RandomUtil.randomNumbers(6));
        }
        memberUserMapper.insert(user);

        // 注册赠送积分,开了线下的城市不送
        TradeConfigRespDTO config = tradeConfigApi.getTradeConfig();
        if(CollectionUtils.isAnyEmpty(config.getOpenCityAreas())){
            if(configRespDTO.getRegPoint() > 0){
                memberPointRecordService.createPointRecord(user.getId(), configRespDTO.getRegPoint(), MemberPointBizTypeEnum.REGISTER, String.valueOf(user.getId()));
            }
        }else{
            AddressRespDTO address = tradeConfigApi.getAddressByIp(getClientIP());
            if(!config.getOpenCityAreas().contains(address.getProvince())){
                if(configRespDTO.getRegPoint() > 0){
                    memberPointRecordService.createPointRecord(user.getId(), configRespDTO.getRegPoint(), MemberPointBizTypeEnum.REGISTER, String.valueOf(user.getId()));
                }
            }
        }

        // 发送 MQ 消息：用户创建
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {

            @Override
            public void afterCommit() {
                memberUserProducer.sendUserCreateMessage(user.getId());
            }

        });
        return user;
    }

    @Override
    public void updateUserLogin(Long id, String loginIp) {
        memberUserMapper.updateById(new MemberUserDO().setId(id)
                .setLoginIp(loginIp).setCity(IPUtils.getArea(loginIp).getName()).setLoginDate(LocalDateTime.now()));
    }

    @Override
    public MemberUserDO getUser(Long id) {
        return memberUserMapper.selectById(id);
    }

    @Override
    public List<MemberUserDO> getUserList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return ListUtil.empty();
        }
        return memberUserMapper.selectBatchIds(ids);
    }

    @Override
    public void updateUser(Long userId, AppMemberUserUpdateReqVO reqVO) {
        TradeConfigRespDTO config = tradeConfigApi.getTradeConfig();
        if(!config.getAuthEnabled() && config.getQrcodeEnabled()){
            if(!mpUserApi.getQrcode(userId)){
                throw exception(USER_FANS_QRCODE);
            }
        }

        MemberUserDO memberUserDO = memberUserMapper.selectById(userId);

        // 性别不能修改
        if(memberUserDO.getSex() != null){
            if(SexEnum.MALE.getSex().equals(memberUserDO.getSex()) || SexEnum.FEMALE.getSex().equals(memberUserDO.getSex())){
                reqVO.setSex(memberUserDO.getSex());
            }
        }

        if(StringUtils.isNotBlank(reqVO.getNickname())){
            if(reqVO.getNickname().contains("用户")){
                throw exception(USER_NICKNAME_EMPTY);
            }

            if(StringUtils.isBlank(memberUserDO.getNickname()) || !reqVO.getNickname().equals(memberUserDO.getNickname())){
                boolean check = true;
                try {
                    check = tradeConfigApi.checkMessage(reqVO.getNickname(), String.valueOf(userId));
                }catch (Exception e){
                    throw exception(USER_UPDATE_ERROR);
                }
                if(!check){
                    throw exception(USER_NICKNAME_ERROR);
                }
            }
        }

        if(StringUtils.isNotBlank(reqVO.getQrcode())){
            if(StringUtils.isBlank(memberUserDO.getQrcode()) || !reqVO.getQrcode().equals(memberUserDO.getQrcode())){
                String url = socialClientApi.getQrCode(reqVO.getQrcode());
                if(StringUtils.isBlank(url)){
                    reqVO.setQrcode(null);
                    //throw exception(USER_QRCODE_ERROR);
                }else{
                    if(!url.contains("https://u.wechat.com")){
                        reqVO.setQrcode(null);
                        //throw exception(USER_QRCODE_ERROR);
                    }
                }
            }
        }

        if(StringUtils.isNotBlank(reqVO.getPhoto())){
            if(StringUtils.isBlank(memberUserDO.getPhoto()) || !reqVO.getPhoto().equals(memberUserDO.getPhoto())){
                String[] imgArr = reqVO.getPhoto().split(",");
                for(String img : imgArr){

                    String url = socialClientApi.getQrCode(img);
                    if(StringUtils.isNotBlank(url)){
                        throw exception(USER_PHOTO_QRCODE);
                    }

                    boolean check = true;

                    try {
                        check = tradeConfigApi.checkImg(img, String.valueOf(userId));
                    }catch (Exception e){
                        throw exception(USER_UPDATE_ERROR);
                    }
                    if(!check){
                        throw exception(USER_PHOTO_ERROR);
                    }

                }

            }
        }

        if(StringUtils.isNotBlank(reqVO.getAvatar())){
            if(StringUtils.isBlank(memberUserDO.getAvatar()) || !reqVO.getAvatar().equals(memberUserDO.getAvatar())){
                String url = socialClientApi.getQrCode(reqVO.getAvatar());
                if(StringUtils.isNotBlank(url)){
                    throw exception(USER_AVATAR_QRCODE);
                }

                boolean check = true;
                try {
                    check = tradeConfigApi.checkImg(reqVO.getAvatar(), String.valueOf(userId));
                }catch (Exception e){
                    throw exception(USER_UPDATE_ERROR);
                }
                if(!check){
                    throw exception(USER_AVATAR_ERROR);
                }
            }
        }

        MemberUserDO updateObj = BeanUtils.toBean(reqVO, MemberUserDO.class).setId(userId);
        updateObj.setCity(IPUtils.getArea(getClientIP()).getName());
        updateObj.setVisible(true);

        if(config.getFriendEnabled()){
            // 开通交友才显示
            if(StringUtils.isNotBlank(updateObj.getPhoto())){
                updateObj.setIsWelcome(CommonStatusEnum.ENABLE.getStatus());
            }else{
                updateObj.setIsWelcome(CommonStatusEnum.DISABLE.getStatus());
            }
        }
        memberUserMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserMobile(Long userId, AppMemberUserUpdateMobileReqVO reqVO) {
        // 1.1 检测用户是否存在
        MemberUserDO user = validateUserExists(userId);
        // 1.2 校验新手机是否已经被绑定
        validateMobileUnique(null, reqVO.getMobile());

        // 2.1 校验旧手机和旧验证码
        // 补充说明：从安全性来说，老手机也校验 oldCode 验证码会更安全。但是由于 uni-app 商城界面暂时没做，所以这里不强制校验
        if (StrUtil.isNotEmpty(reqVO.getOldCode())) {
            smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(user.getMobile()).setCode(reqVO.getOldCode())
                    .setScene(SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene()).setUsedIp(getClientIP()));
        }
        // 2.2 使用新验证码
        smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(reqVO.getMobile()).setCode(reqVO.getCode())
                .setScene(SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene()).setUsedIp(getClientIP()));

        // 3. 更新用户手机
        memberUserMapper.updateById(MemberUserDO.builder().id(userId).mobile(reqVO.getMobile()).build());
    }

    @Override
    public void updateUserMobileByWeixin(Long userId, AppMemberUserUpdateMobileByWeixinReqVO reqVO) {
        // 1.1 获得对应的手机号信息
        SocialWxPhoneNumberInfoRespDTO phoneNumberInfo = socialClientApi.getWxMaPhoneNumberInfo(
                UserTypeEnum.MEMBER.getValue(), reqVO.getCode());
        Assert.notNull(phoneNumberInfo, "获得手机信息失败，结果为空");
        // 1.2 校验新手机是否已经被绑定
        validateMobileUnique(userId, phoneNumberInfo.getPhoneNumber());

        // 2. 更新用户手机
        memberUserMapper.updateById(MemberUserDO.builder().id(userId).mobile(phoneNumberInfo.getPhoneNumber()).build());
    }

    @Override
    public void updateUserPassword(Long userId, AppMemberUserUpdatePasswordReqVO reqVO) {
        // 检测用户是否存在
        MemberUserDO user = validateUserExists(userId);
        // 校验验证码
        smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(user.getMobile()).setCode(reqVO.getCode())
                .setScene(SmsSceneEnum.MEMBER_UPDATE_PASSWORD.getScene()).setUsedIp(getClientIP()));

        // 更新用户密码
        memberUserMapper.updateById(MemberUserDO.builder().id(userId)
                .password(passwordEncoder.encode(reqVO.getPassword())).build());
    }

    @Override
    public void resetUserPassword(AppMemberUserResetPasswordReqVO reqVO) {
        // 检验用户是否存在
        MemberUserDO user = validateUserExists(reqVO.getMobile());

        // 使用验证码
        smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.MEMBER_RESET_PASSWORD,
                getClientIP()));

        // 更新密码
        memberUserMapper.updateById(MemberUserDO.builder().id(user.getId())
                .password(passwordEncoder.encode(reqVO.getPassword())).build());
    }

    private MemberUserDO validateUserExists(String mobile) {
        MemberUserDO user = memberUserMapper.selectByMobile(mobile);
        if (user == null) {
            throw exception(USER_MOBILE_NOT_EXISTS);
        }
        return user;
    }

    @Override
    public boolean isPasswordMatch(String rawPassword, String encodedPassword) {
        return passwordEncoder.matches(rawPassword, encodedPassword);
    }

    /**
     * 对密码进行加密
     *
     * @param password 密码
     * @return 加密后的密码
     */
    private String encodePassword(String password) {
        return passwordEncoder.encode(password);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(MemberUserUpdateReqVO updateReqVO) {
        // 校验存在
        validateUserExists(updateReqVO.getId());
        // 校验手机唯一
        validateMobileUnique(updateReqVO.getId(), updateReqVO.getMobile());

        // 更新
        MemberUserDO updateObj = MemberUserConvert.INSTANCE.convert(updateReqVO);
        memberUserMapper.updateById(updateObj);
    }

    @VisibleForTesting
    MemberUserDO validateUserExists(Long id) {
        if (id == null) {
            return null;
        }
        MemberUserDO user = memberUserMapper.selectById(id);
        if (user == null) {
            throw exception(USER_NOT_EXISTS);
        }
        return user;
    }

    @VisibleForTesting
    void validateMobileUnique(Long id, String mobile) {
        if (StrUtil.isBlank(mobile)) {
            return;
        }
        MemberUserDO user = memberUserMapper.selectByMobile(mobile);
        if (user == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的用户
        if (id == null) {
            throw exception(USER_MOBILE_USED, mobile);
        }
        if (!user.getId().equals(id)) {
            throw exception(USER_MOBILE_USED, mobile);
        }
    }

    @Override
    public PageResult<MemberUserDO> getUserPage(MemberUserPageReqVO pageReqVO) {
        return memberUserMapper.selectPage(pageReqVO);
    }

    @Override
    public void updateUserLevel(Long id, Long levelId, Integer experience) {
        // 0 代表无等级：防止UpdateById时，会被过滤掉的问题
        levelId = ObjectUtil.defaultIfNull(levelId, 0L);
        memberUserMapper.updateById(new MemberUserDO()
                .setId(id)
                .setLevelId(levelId).setExperience(experience)
        );
    }

    @Override
    public Long getUserCountByGroupId(Long groupId) {
        return memberUserMapper.selectCountByGroupId(groupId);
    }

    @Override
    public Long getUserCountByLevelId(Long levelId) {
        return memberUserMapper.selectCountByLevelId(levelId);
    }

    @Override
    public Long getUserCountByTagId(Long tagId) {
        return memberUserMapper.selectCountByTagId(tagId);
    }

    @Override
    public boolean updateUserPoint(Long id, Integer point) {
        if (point > 0) {
            memberUserMapper.updatePointIncr(id, point);
        } else if (point < 0) {
            return memberUserMapper.updatePointDecr(id, point) > 0;
        }
        return true;
    }

    @Override
    public PageResult<MemberUserDO> getMemberUserInfoPage(AppMemberUserInfoPageReqVO pageReqVO) {
        return memberUserMapper.selectPage(pageReqVO);
    }

    @Override
    public boolean updateUserWeixin(Long userId, String weixin) {
        MemberUserDO userDO = memberUserMapper.selectById(userId);
        userDO.setWeixin(weixin);
        memberUserMapper.updateById(userDO);
        return true;
    }

    @Override
    public void DisabledUser(Long userId) {
        MemberUserDO member = memberUserMapper.selectById(userId);
        Date date = DateUtil.offsetHour(DateUtil.date(), 24);
        member.setDisabledTime(DateUtil.toLocalDateTime(date));
        memberUserMapper.updateById(member);
    }

    @Override
    public List<MemberUserDO> getWeekTopList(Integer sex) {
        return memberUserMapper.getWeekTopList(sex);
    }

    @Override
    public List<MemberUserDO> getMemberHotList() {
        return memberUserMapper.getMemberHotList();
    }

    @Override
    public List<MemberUserDO> getMemberNewList() {
        return memberUserMapper.getMemberNewList();
    }

    @Override
    public void updateUserSlashed(Long userId) {
        // TODO 后面可能要加置顶记录
        MemberUserDO member = memberUserMapper.selectById(userId);
        Integer point = 200;
        if(member.getPoint() < point){
            if(member.getVipEndTime() == null){
                throw exception(MEMBER_VIP_SLASHED);
            }else{
                if(member.getVipEndTime().isBefore(DateUtil.toLocalDateTime(DateUtil.date()))){
                    throw exception(MEMBER_VIP_SLASHED);
                }else{
                    // 用户置顶免费
                    DateTime lastSecondOfDay = DateUtil.endOfDay(DateUtil.date());
                    if(member.getPostTime() == null){
                        member.setPostTime(DateUtil.toLocalDateTime(lastSecondOfDay));
                        member.setPostNum(3);
                        member.setSlashedNum(3);
                        member.setWechatNum(5);

                        point = 0;
                        Integer slashedNum = member.getSlashedNum()-1;
                        member.setSlashedNum(slashedNum);
                    }else{
                        if(DateUtil.toLocalDateTime(DateUtil.date()).isAfter(member.getPostTime())){
                            member.setPostTime(DateUtil.toLocalDateTime(lastSecondOfDay));
                            member.setPostNum(3);
                            member.setSlashedNum(3);
                            member.setWechatNum(5);
                        }

                        if(member.getSlashedNum() > 0){
                            point = 0;
                            Integer slashedNum = member.getSlashedNum()-1;
                            if(slashedNum < 0){
                                slashedNum = 0;
                            }
                            member.setSlashedNum(slashedNum);
                        }else{
                            throw exception(MEMBER_SLASHED);
                        }
                    }
                }
            }
        }

        if(member.getSlashedTime() == null){
            Date slashedTime = DateUtil.offsetHour(DateUtil.date(), 3);
            member.setSlashedTime(DateUtil.toLocalDateTime(slashedTime));
        }else{
            if(member.getSlashedTime().isAfter(DateUtil.toLocalDateTime(DateUtil.date()))){
               Date slashedTime = DateUtil.offsetHour(new DateTime(member.getSlashedTime()), 3);
               member.setSlashedTime(DateUtil.toLocalDateTime(slashedTime));
            }else{
                Date slashedTime = DateUtil.offsetHour(DateUtil.date(), 3);
                member.setSlashedTime(DateUtil.toLocalDateTime(slashedTime));
            }
        }
        memberUserMapper.updateById(member);
        // 消耗积分
        if(point > 0){
            memberPointApi.reducePoint(userId, point, MemberPointBizTypeEnum.MEMBER_SLASHED.getType(), String.valueOf(member.getId()));
        }
    }

    @Override
    public MemberUserDO getRandomUser(Long userId) {
        MemberUserDO memberUserDO = memberUserMapper.getRandomUser(userId);
        if(memberUserDO == null){
            // 匹配不到，重新匹配
            memberUserDO = memberUserMapper.getRandomMember(userId);
        }
        return memberUserDO;
    }

    @Override
    public void updateUserMatchNum(Long id, Integer matchNum, Integer matchCount, LocalDateTime matchTime) {
        memberUserMapper.updateUserMatchNum(id, matchNum, matchCount, matchTime);
    }

    @Override
    public String getQrcodeByUserId(Long loginUserId, Long userId) {
        MemberUserDO member = memberUserMapper.selectById(loginUserId);
        MemberUserDO receiveMember = memberUserMapper.selectById(userId);

        if(CommonStatusEnum.isDisable(member.getStatus())){
            throw exception(AUTH_LOGIN_USER_DISABLED);
        }

        if(StringUtils.isBlank(receiveMember.getQrcode())){
            throw exception(MEMBER_QRCODE_EMPTY);
        }

        Integer point = 200;
        if(member.getPoint() < point){
            if(member.getVipEndTime() == null){
                throw exception(MEMBER_VIP_QRCODE);
            }else{
                if(member.getVipEndTime().isBefore(DateUtil.toLocalDateTime(DateUtil.date()))){
                    throw exception(MEMBER_VIP_QRCODE);
                }else{
                    // 会员交换名片免费
                    DateTime lastSecondOfDay = DateUtil.endOfDay(DateUtil.date());
                    if(member.getPostTime() == null){
                        member.setPostTime(DateUtil.toLocalDateTime(lastSecondOfDay));
                        member.setPostNum(3);
                        member.setSlashedNum(3);
                        member.setWechatNum(5);

                        point = 0;
                        Integer wechatNum = member.getWechatNum()-1;
                        member.setWechatNum(wechatNum);
                    }else{
                        if(DateUtil.toLocalDateTime(DateUtil.date()).isAfter(member.getPostTime())){
                            member.setPostTime(DateUtil.toLocalDateTime(lastSecondOfDay));
                            member.setPostNum(3);
                            member.setSlashedNum(3);
                            member.setWechatNum(5);
                        }

                        if(member.getWechatNum() > 0){
                            point = 0;
                            Integer wechatNum = member.getWechatNum()-1;
                            if(wechatNum < 0){
                                wechatNum = 0;
                            }
                            member.setWechatNum(wechatNum);
                        }else{
                            throw exception(MEMBER_QRCODE);
                        }
                    }
                }
            }


        }

        if(point > 0){
            // 消耗积分
            memberPointApi.reducePoint(loginUserId, point, MemberPointBizTypeEnum.MEMBER_QRCODE.getType(), String.valueOf(userId));

            // 奖励积分
            memberPointApi.addPoint(userId, point/2, MemberPointBizTypeEnum.MEMBER_QRCODE_VIEW.getType(), String.valueOf(loginUserId));
        }

        return receiveMember.getQrcode();
    }

    @Override
    public List<MemberUserDO> getUserListByUser() {
        return memberUserMapper.getMemberList();
    }

    @Override
    public void updateUserVipEndTime(Long userId, Integer day) {
        MemberUserDO memberUserDO = memberUserMapper.selectById(userId);
        if(memberUserDO.getVipEndTime() == null){
            DateTime dateTime = DateUtil.offsetDay(DateUtil.date(), day);
            memberUserDO.setVipEndTime(DateUtil.toLocalDateTime(dateTime));
        }else{
            if(memberUserDO.getVipEndTime().isAfter(DateUtil.toLocalDateTime(DateUtil.date()))){
                DateTime dateTime = DateUtil.offsetDay(new DateTime(memberUserDO.getVipEndTime()), day);
                memberUserDO.setVipEndTime(DateUtil.toLocalDateTime(dateTime));
            }else {
                DateTime dateTime = DateUtil.offsetDay(DateUtil.date(), day);
                memberUserDO.setVipEndTime(DateUtil.toLocalDateTime(dateTime));
            }
        }
        memberUserMapper.updateById(memberUserDO);
    }

    @Override
    public void updateUserVip(Long userId, LocalDateTime postTime, Integer postNum, Integer wechatNum, Integer slashedNum) {
        MemberUserDO memberUserDO = memberUserMapper.selectById(userId);
        memberUserDO.setPostTime(postTime);
        memberUserDO.setPostNum(postNum);
        memberUserDO.setWechatNum(wechatNum);
        memberUserDO.setSlashedNum(slashedNum);
        memberUserMapper.updateById(memberUserDO);
    }

    @Override
    public void updateUserVisitNum(Long userId) {
        MemberUserDO memberUserDO = memberUserMapper.selectById(userId);
        memberUserDO.setVisitNum(memberUserDO.getVisitNum()+1);
        memberUserMapper.updateById(memberUserDO);
    }

}
